import numpy as np
from matplotlib import pyplot as plt
import math

class Filter():
    def __init__(self, level = 1, order = 2):
        self.level = level
        self.order = order
        self.transition = order - 1
        self.cur_level = 0
        self.init = 0
        self.data = [[0.0]*order]*level
        self.output = [0.0]*level

    @staticmethod
    def mean_without_zero(arr):
        sum = 0
        count = 0
        for i in arr:
            if not i == 0.0:
                sum += i
                count += 1
        if not count == 0:
            return sum / count
        else:
            return 0.0

    def mean_filter(self,input):

        self.data[self.cur_level] = self.data[self.cur_level][1:]
        self.data[self.cur_level].append(input)


        if self.data[self.cur_level][-2] == 0.0:
            self.output[self.cur_level] = input
        else:
            self.output[self.cur_level] = Filter.mean_without_zero(self.data[self.cur_level])

        self.cur_level += 1

        if self.cur_level == self.level:
            self.cur_level = 0
            return self.output[-1]
        else:
            return self.mean_filter(self.output[self.cur_level-1]) # 递归调用
        
    def mean_filter_thres(self,input,thres = 90):

        self.data[self.cur_level] = self.data[self.cur_level][1:]
        self.data[self.cur_level].append(input)

        if input > thres:
            self.output[self.cur_level] = input
            return input
        else:
            self.output[self.cur_level] = Filter.mean_without_zero(self.data[self.cur_level][self.transition:])

        self.cur_level += 1

        if self.cur_level == self.level:
            if not self.transition == 0:
                self.transition -= 1
            self.cur_level = 0
            return self.output[-1]
        else:
            return self.mean_filter_thres(self.output[self.cur_level-1]) # 递归调用

# x = []
# for i in range(100):
#     if i < 20:
#         x.append(20 * math.exp(-i/10) - 0.1)
#     else:
#         x.append(20 * math.exp(-i/10) + np.random.normal(loc=0.0, scale=1.0, size=None) - 0.1)

# y = []
# ft = Filter(2,6)
# for xi in x:
#     y.append(ft.mean_filter_thres(xi))

# print(x[0],y[0])

# plt.title('Approach mean filter')
# plt.plot(range(len(x)),x)
# plt.plot(range(len(y)),y,'r')
# plt.show()


    